Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Saved Objects] Update the migrationVersion property to hold a plain string value #150075

Merged
merged 12 commits into from
Mar 24, 2023

Conversation

dokmic
Copy link
Contributor

@dokmic dokmic commented Feb 1, 2023

Summary

Resolves #70815.

Checklist

For maintainers

@dokmic dokmic changed the title [Saved Objects] [Saved Objects] Update the migrationVersion property to hold a plain string value Feb 1, 2023
@dokmic dokmic force-pushed the feature/70815 branch 3 times, most recently from 91bd29b to 68ddd12 Compare February 20, 2023 11:08
@dokmic dokmic force-pushed the feature/70815 branch 3 times, most recently from 673b578 to cb5b1e4 Compare March 8, 2023 10:18
@dokmic dokmic force-pushed the feature/70815 branch 4 times, most recently from 4e3aa3a to 89301b2 Compare March 10, 2023 08:26
@dokmic dokmic marked this pull request as ready for review March 20, 2023 12:56
@dokmic dokmic requested review from a team as code owners March 20, 2023 12:56
@dokmic dokmic added review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc Feature:Saved Objects release_note:skip Skip the PR/issue when compiling release notes Feature:Migrations v8.8.0 labels Mar 20, 2023
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-core (Team:Core)

@dokmic dokmic added the backport:skip This commit does not require backporting label Mar 20, 2023
@dokmic dokmic requested review from rudolf and pgayvallet March 20, 2023 12:58
Copy link
Contributor

@vadimkibana vadimkibana left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see SharedUX is tagged for review because of src/plugins/home/server/services/sample_data, changes in sample LGTM.

Copy link
Contributor

@nreese nreese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kibana-gis changes LGTM

Copy link
Member

@jgowdyelastic jgowdyelastic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ML changes LGTM

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just did a first pass and will go through the code in more detail again.

We're technically making a breaking change to the API by not responding with migrationVersion anymore. It's hard to know if external integratinos ever rely on this field but we should rather be safe than sorry.

I think we can add a very light-weight compatibility layer by basically applying the transformation from packages/core/saved-objects/core-saved-objects-migration-server-internal/src/document_migrator/migrations/transform_migration_version.ts (and it's opposite) at the API layer. That way the API stays 100% the same.

That means we can remove migrationVersion in all the rest of our code like the documentMigrator and saved objects typescript APIs as well.

@@ -159,6 +159,9 @@ export function getBaseMappings(): IndexMapping {
coreMigrationVersion: {
type: 'keyword',
},
typeMigrationVersion: {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can't comment at the right place, but we should remove the mapping for migrationVersion on line 124

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot remove that yet as we are updating mappings when there are still documents with the old migrationVersion properties. That happens before we apply core migrations.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing a field will mean the migration algorithm doesn't think we've made an incompatible mappings change, so it would re-use the index instead of creating a new one. But mappings updates are commutative, so even if we update the mappings without migrationVersion ES will still keep it on existing indices.

Whenever we create a new index we should run the OUTDATED_DOCUMENTS_TRANSFORM* steps before we apply the final mappings to the index.

So I can't really imagine where this would fail?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I think this is because we don't check for coreMigrationVersion in the outdatedDocumentsQuery. So unless:
a) there's incompatible mappings and we reindex all documents
b) all saved object types have a new typeMigrationVersion (unlikely)

Some documents will be the old coreMigrationVersion and require the migrationVersion mapping.

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall great job, this was some massive work.

Regarding the HTTP APIs, even if I personally think that it would probably be fine for 99% of the usages, I'm forced to agree with @rudolf on the fact that we should probably be cautious, and try to preserve the existing shape for responses when possible.

My other comments and remarks:

Comment on lines 117 to +119
...(migrationVersion && { migrationVersion }),
...(coreMigrationVersion && { coreMigrationVersion }),
...(typeMigrationVersion != null ? { typeMigrationVersion } : {}),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: There's a subtle difference of behavior between typeMigrationVersion and the other attributes here (X && { X } vs X != null ? { X } : {}) . Not saying that one is better than the other, but isn't that a risk somehow to have this specific prop handled differently here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good notice. That's done so to keep backward compatibility -- previously, we used migrationVersion: {} to trigger migrations, but now an empty string does that trick. In order to keep the value, we are using this ternary operator.

private convertNamespaceTypes: boolean
) {}

protected *getPipeline(): Generator<Transform> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was going to say that I wasn't sure a generator was really necessary given that the migration workstream is predictable, but actually because of the edge case of type switch, it's not 😄

As a side note for later me/us, we will need to break/remove that type switching capability for ZDT

Comment on lines +52 to +61
must: [
{ term: { type } },
{
bool: {
should: [
{
bool: {
must: { exists: { field: 'migrationVersion' } },
must_not: { term: { [`migrationVersion.${type}`]: latestVersion } },
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Backlinking #153031, because the equivalent query for the zdt algorithm will have to be adapted too.

@@ -118,7 +118,7 @@ describe('migration v2', () => {
await root.preboot();
await root.setup();
await expect(root.start()).rejects.toMatchInlineSnapshot(
`[Error: Unable to complete saved object migrations for the [.kibana] index: The document with _id "canvas-workpad-template:workpad-template-061d7868-2b4e-4dc8-8bf7-3772b52926e5" is 1715272 bytes which exceeds the configured maximum batch size of 1015275 bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.]`
`[Error: Unable to complete saved object migrations for the [.kibana] index: The document with _id "canvas-workpad-template:workpad-template-061d7868-2b4e-4dc8-8bf7-3772b52926e5" is 1715248 bytes which exceeds the configured maximum batch size of 1015275 bytes. To proceed, please increase the 'migrations.maxBatchSizeBytes' Kibana configuration option and ensure that the Elasticsearch 'http.max_content_length' configuration option is set to an equal or larger value.]`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: Outside of the scope of this PR but we should probably adapt those tests to not assert on the exact size of the documents 🙈

Comment on lines +162 to +164
typeMigrationVersion: {
type: 'version',
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: given we will be converting it to typeMigrationVersion during the migration, do we need to keep the migrationVersion field in our schema?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, we still need it to provide compatible mappings.

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
@kbn/core-saved-objects-server 98 99 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
core 351.1KB 351.3KB +182.0B

Saved Objects .kibana field count

Every field in each saved object type adds overhead to Elasticsearch. Kibana needs to keep the total field count below Elasticsearch's default limit of 1000 fields. Only specify field mappings for the fields you wish to search on or query. See https://www.elastic.co/guide/en/kibana/master/saved-objects-service.html#_mappings

id before after diff
typeMigrationVersion - 1 +1
Unknown metric groups

API count

id before after diff
@kbn/core-saved-objects-api-browser 107 109 +2
@kbn/core-saved-objects-api-server 334 338 +4
@kbn/core-saved-objects-server 489 491 +2
total +8

ESLint disabled line counts

id before after diff
securitySolution 433 436 +3

References to deprecated APIs

id before after diff
@kbn/core-saved-objects-api-browser 54 60 +6
@kbn/core-saved-objects-api-server-internal 0 8 +8
@kbn/core-saved-objects-browser-internal 238 251 +13
@kbn/core-saved-objects-browser-mocks 32 35 +3
@kbn/core-saved-objects-import-export-server-internal 56 58 +2
@kbn/core-saved-objects-server-internal 4 6 +2
canvas 151 152 +1
fleet 51 62 +11
graph 82 88 +6
lists 93 95 +2
securitySolution 361 415 +54
total +108

Total ESLint disabled count

id before after diff
securitySolution 513 516 +3

History

  • 💚 Build #114012 succeeded 20efde54bb431632b831bc8f8b4f1cd0457ead69
  • 💚 Build #113233 succeeded 89301b21739c7d900be770c7cdf78923d1586e26
  • 💚 Build #113159 succeeded 4e3aa3a14562558412d27df94ae760cae265b819
  • 💔 Build #113139 failed 1a869a731690a4941024591626a53d489e3ae3dc
  • 💚 Build #112922 succeeded 4edf0e1d11ba8bd173c834bc9122dc06ab78c2b4
  • 💔 Build #112873 failed 6b69a097668cc5a70b69496bd69a70aab4d0d4a6

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@pgayvallet pgayvallet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

In addition to the endpoints BWC, we probably want to open a follow-up issue to talk about whether we should change the migration algorithm(s) to forcefully migrate all documents when coreMigrationVersion changes.

Copy link
Contributor

@rudolf rudolf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will create an issue for fixing API compatibility and migrationVersion mappings in a separate PR

@dokmic dokmic merged commit 17876df into elastic:main Mar 24, 2023
@dokmic dokmic deleted the feature/70815 branch March 24, 2023 12:46
jennypavlova pushed a commit to jennypavlova/kibana that referenced this pull request Mar 24, 2023
…n string value (elastic#150075)

* Update document migrator to rely on `typeMigrationVersion` instead of `migrationVersion`.
* Refactor document migrator to extract migration pipeline logic.
* Add `core` migration type.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:Migrations Feature:Saved Objects release_note:skip Skip the PR/issue when compiling release notes review Team:Core Core services & architecture: plugins, logging, config, saved objects, http, ES client, i18n, etc v8.8.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Saved Objects should reduce the migrationVersion field count
8 participants